﻿using QFramework;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using Game.Assets.Scripts.Model;
using Game.Command;

namespace Game.System
{
    public class TimerHelper : MonoBehaviour, IController
    {
        TimerModel timerModel;

        public IArchitecture GetArchitecture()
        {
            return APP.Interface;
        }

        private void Awake()
        {
            this.timerModel = this.GetModel<TimerModel>();
            DontDestroyOnLoad(gameObject);
        }
        private void Update()
        {
            if (timerModel.WaitAddTimerDic.Count > 0 || timerModel.WaitRemoveTimers.Count > 0)
            {
                this.SendCommand<UpdateTimerDicCommand>();
            }

            foreach (int item in timerModel.TimerDic.Keys)
            {
                if (!timerModel.PauseTimer.Contains(item) && timerModel.TimerDic[item].Value > 0)
                {
                    float mul = 1;
                    if (timerModel.TimerMultiplyDic.ContainsKey(item) && timerModel.TimerMultiplyDic[item].duration > 0)
                    {
                        mul = timerModel.TimerMultiplyDic[item].multiply;
                        this.SendCommand(new SetTimerMultiplierCommand(item, timerModel.TimerMultiplyDic[item].duration - Time.deltaTime, timerModel.TimerMultiplyDic[item].multiply));
                    }
                    this.SendCommand(new UpdateTimerCommand(item, timerModel.TimerDic[item].Value - Time.deltaTime * mul));
                }
            }
        }
    }

    /// <summary>
    /// 计时器
    /// </summary>
    public class TimerSystem : AbstractSystem
    {

        int curId;
        TimerModel timerModel;
        protected override void OnInit()
        {
            timerModel = this.GetModel<TimerModel>();
            new GameObject("TimerSystem").AddComponent<TimerHelper>();
            this.RegisterEvent<RegisterTimerEvent>(arg =>
            {
                Register(arg.time);
            });
            this.RegisterEvent<EnforcementTimerEvent>(arg =>
            {
                EnforcementCD(arg.id, arg.time);
            });
            this.RegisterEvent<RemoveTimerEvent>(arg =>
            {
                timerModel.WaitRemoveTimers.Add(arg.id);
            });
        }

        public IUnRegister Register(float time)
        {
            curId++;
            BindableProperty<float> timer = new BindableProperty<float>(time * 60);
            timerModel.WaitAddTimerDic.Add(curId, timer);
            TypeEventSystem.Global.Send(new ActivateTimerEvent() { id = curId, timer = timer });
            return new CustomUnRegister(() => { UnRegister(curId); });
        }

        /// <summary>
        /// 在现 CD 基础上减少
        /// </summary>
        /// <param name="id"></param>
        /// <param name="inc"></param>
        public void ReduceCD(int id, float time)
        {
            if (timerModel.TimerDic[id].Value > 0 && !timerModel.PauseTimer.Contains(id))
            {
                timerModel.TimerDic[id].Value -= time;
            }
        }
        /// <summary>
        /// 将id1计时器的时间累加到id2计时器上，并和选择是否移除id1计时器
        /// </summary>
        /// <param name="id1"></param>
        /// <param name="id2"></param>
        /// <param name="limt">累加值不会超过这个上限</param>
        /// <param name="isRemove">true:移除id1计时器</param>
        public void AccumulationTimer(int id1, int id2, float limt, bool isRemove)
        {
            limt *= 60;
            timerModel.TimerDic[id2].SetValueWithoutEvent(timerModel.TimerDic[id2].Value + timerModel.TimerDic[id1].Value);
            timerModel.TimerDic[id2].Value = timerModel.TimerDic[id2].Value > limt ? limt : timerModel.TimerDic[id2].Value;
            if (isRemove)
            {
                timerModel.TimerDic.Remove(id1);
            }
        }
        /// <summary>
        /// 将 CD 强制设置到设定值
        /// </summary>
        /// <param name="id"></param>
        /// <param name="value"></param>
        public void EnforcementCD(int id, float value)
        {
            timerModel.TimerDic[id].Value = value * 60;
        }
        /// <summary>
        /// 暂停计时器
        /// </summary>
        /// <param name="id"></param>
        /// <param name="isPause"></param>
        public void Pause(int id, bool isPause)
        {
            if (isPause)
            {
                if (!timerModel.PauseTimer.Contains(id))
                {
                    timerModel.PauseTimer.Add(id);
                }
            }
            else
            {
                timerModel.PauseTimer.Remove(id);
                TypeEventSystem.Global.Send(new ActivateTimerEvent() { id = id, timer = timerModel.TimerDic[id] });
            }
        }
        void UnRegister(int id)
        {
            timerModel.TimerDic.Remove(id);
        }


    }
}